package com.freesky.common.utils.file;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

@Component
public class OssUtils {

    @Value("${oss.accessId}")
    private String accessId;

    @Value("${oss.accessKey}")
    private String accessKey;

    @Value("${oss.endpoint}")
    private String endpoint;

    @Value("${oss.bucket}")
    private String bucket;

    @Value("${oss.host}")
    private String host;

    @Value("${oss.callbackUrl}")
    private String callbackUrl;


    private String FULL_ACCESS_ID = "LTAI5tShcNDz3op5rgqmRvRX";
    private String FULL_ACCESS_SECRET = "6iRyQaMCWQw6OZzqnhU2VIktnzeJEj";

    public OSSClient initClient() throws Exception{
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(10000);
        conf.setMaxErrorRetry(10);

        DefaultCredentialProvider provider = new DefaultCredentialProvider(accessId, accessKey);
        OSSClient client = new OSSClient(endpoint, provider, conf);
        return client;
    }

    public Map<String, String> generalSignInfo(String dir,String id) throws Exception{

        OSSClient client = initClient();

        long expireTime = 60*1000;
        long expireEndTime = System.currentTimeMillis() + expireTime * 1000;

        Date expiration = new Date(expireEndTime);
        PolicyConditions policyConds = new PolicyConditions();
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
        policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

        String postPolicy = client.generatePostPolicy(expiration, policyConds);
        byte[] binaryData = postPolicy.getBytes("utf-8");
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String postSignature = client.calculatePostSignature(postPolicy);

        Map<String, String> respMap = new LinkedHashMap<String, String>();
        respMap.put("accessid", accessId);
        respMap.put("policy", encodedPolicy);
        respMap.put("signature", postSignature);
        respMap.put("dir", dir);
        respMap.put("id",id);
        respMap.put("host", host);
        respMap.put("expire", String.valueOf(expireEndTime / 1000));

        JSONObject jasonCallback = new JSONObject();
        jasonCallback.put("callbackUrl", callbackUrl);
        jasonCallback.put("callbackHost", "web.0591ysd.com");
        jasonCallback.put("callbackBody",
                "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
        jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
        String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
        respMap.put("callback", base64CallbackBody);
        return respMap;
    }

    public String generalURL(String key) throws Exception {
        OSSClient client = initClient();

        long expireTime = 60*1000;
        long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
        Date expiration = new Date(expireEndTime);

        URL url = client.generatePresignedUrl(bucket, key, expiration);
        return url.toString();
    }

    /**
     * https://help.aliyun.com/document_detail/64555.html?spm=a2c6h.12873639.0.0.3f2243ee2N7vjg
     * @param key
     * @param seconds  生成指定秒数的封面图片
     * @return
     * @throws Exception
     */
    public String generalFramePicture(String key,int seconds) throws Exception {
        OSSClient client = initClient();

        long expireTime = 60*1000;
        long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
        Date expiration = new Date(expireEndTime);
        String style = "video/snapshot,t_"+ (seconds * 1000)+",m_fast,f_jpg";

        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucket, key, HttpMethod.GET);
        req.setExpiration(expiration);
        req.setProcess(style);
        URL url = client.generatePresignedUrl(req);
        return url.toString();
    }

    public int uploadFile(String key,String filePath){
        int resultCode = 0;
        OSS ossClient = new OSSClientBuilder().build(endpoint,
                FULL_ACCESS_ID, FULL_ACCESS_SECRET);
        try{
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucket,key,
                    new File(filePath));
            ossClient.putObject(putObjectRequest);
        } catch (Exception ioe){
            ioe.printStackTrace();
            resultCode = -1;
        } finally {
            ossClient.shutdown();
        }
        return resultCode;
    }

    public int uploadFileStream(String key, InputStream inputStream){
        int resultCode = 0;
        OSS ossClient = new OSSClientBuilder().build(endpoint,
                FULL_ACCESS_ID, FULL_ACCESS_SECRET);
        try{
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucket,key,
                    inputStream);
            ossClient.putObject(putObjectRequest);

        } catch (Exception ioe){
            ioe.printStackTrace();
            resultCode = -1;
        } finally {
            ossClient.shutdown();
        }
        return resultCode;
    }

    public String getFileFromOss(String key){
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();

        OSS ossClient = new OSSClientBuilder().build(endpoint,
                FULL_ACCESS_ID, FULL_ACCESS_SECRET);
        try{
            OSSObject ossObject = ossClient.getObject(bucket, key);
            BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
            byte[] buffer = new byte[4096];
            int len = -1;
            while ((len = in.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            in.close();

        } catch (Exception ioe){
            ioe.printStackTrace();
        } finally {
            ossClient.shutdown();
        }
        return Base64Encoder.encode(outSteam.toByteArray());
    }

    public void getFileFromOss(String key,String filePath){
        OSS ossClient = new OSSClientBuilder().build(endpoint,
                FULL_ACCESS_ID, FULL_ACCESS_SECRET);
        try{
            OSSObject ossObject = ossClient.getObject(bucket, key);
            BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
            FileUtil.writeFromStream(in,new File(filePath));
            in.close();
        } catch (Exception ioe){
            ioe.printStackTrace();
        } finally {
            ossClient.shutdown();
        }
    }

}